#include "pcf8574.h"


u8 PCF8574_Timer;

void I2C_Start(void)
{ 
  taskENTER_CRITICAL();           //进入临界区	
  PCF8574_SDA_OUT;         
  PCF8574_SDA=1;    
  PCF8574_SCL=1;   
  delay_us(5);    
  PCF8574_SDA=0;  
  delay_us(5);   
  PCF8574_SCL=0;
	taskEXIT_CRITICAL();            //退出临界区
}

void I2C_Stop(void)
{  
	taskENTER_CRITICAL();           //进入临界区
	PCF8574_SDA_OUT;     
	PCF8574_SDA=0;    
	PCF8574_SCL=0;   
	delay_us(5);  
	PCF8574_SCL=1;    
	delay_us(5);  
	PCF8574_SDA=1;   
	delay_us(5);
	taskEXIT_CRITICAL();            //退出临界区
}

u8 I2C_Write_Byte(u8 data)
{	
   u8 k;
   taskENTER_CRITICAL();           //进入临界区	
   for(k=0;k<8;k++)
   {
			//发送8bit数据		
     delay_us(5);		
     if(data&0x80)
     {			
       PCF8574_SDA=1;		
     }
     else
     {			
       PCF8574_SDA=0;		
     }		
     data=data<<1;		
     delay_us(5);		
     PCF8574_SCL=1;				
     delay_us(5);		
     PCF8574_SCL=0;	
  }	
  delay_us(5);//延时读取ACK响应	
  PCF8574_SDA=1;  	
  PCF8574_SDA_IN ;//设为输入	
  delay_us(5);	
  PCF8574_SCL=1;   	
  delay_us(5);  	
  k=PCF8574_SDA_DataIN;//读取ACK/NACK	
  delay_us(5);	
  PCF8574_SCL=0;	
  delay_us(5);	
  PCF8574_SDA_OUT;
	taskEXIT_CRITICAL();            //退出临界区
  if(k)
  { 		
     return 0;	//NACK响应
  }	
  return 1;
}

u8 I2C_Read_Byte(u8 flag)
{	
  u32 k,data; 
  taskENTER_CRITICAL();           //进入临界区	
  PCF8574_SDA_IN ; //置为输入线	
  data=0;	
  for(k=0;k<8;k++) //接收8bit数据
  {			
    delay_us(5);		
    PCF8574_SCL=1;		
    delay_us(5);      		
    data=data|PCF8574_SDA_DataIN;//读数据		
    data=data<<1;		
    delay_us(5);		
    PCF8574_SCL=0;		
    delay_us(5); 	
  }	
  data=data>>1;	//往回移动1次	
  PCF8574_SDA_OUT;	//置为输出线	
  if(flag)
  {		
    PCF8574_SDA=1;	//拉高为NACK	
  }
  else
  {		
    PCF8574_SDA=0;	//拉低为ACK	
  }	
  delay_us(5);	
  PCF8574_SCL=1;		
  delay_us(5);	
  PCF8574_SCL=0;	
  delay_us(5);	
  PCF8574_SDA_OUT;
  taskEXIT_CRITICAL();            //退出临界区 	
  return (u8)data;	//返回读取的数据
}

u8 PCF8574_Read(u8 PCF8574TS)
{	
	u8 state;	
	u8 data=0;
	taskENTER_CRITICAL();           //进入临界区
	I2C_Start();									//启动I2C总线	
	state = I2C_Write_Byte(PCF8574TS);		//发送器件地址,主机读	
	if(state == 1)
	{		
		data = I2C_Read_Byte(0x01);	//读取数据			
	}
	else
	{		
		data =-1;	
	}	
	I2C_Stop();	
	taskEXIT_CRITICAL();             //退出临界区	
	return data;
}

u8 PCF8574_Write(u8 PCF8574TS,u8 data)
{	
  u8 state,ret;	
  I2C_Start();									//启动I2C总线	
  state = I2C_Write_Byte(PCF8574TS);	//发送器件地址,主机写	
  if(state==1)
  {	  	
    state = I2C_Write_Byte(data);		
    if(state==1)
    {			
      ret = 1;	 	
    }
    else
    {			
      ret = 0;		
    }	
  }
  else
  {		
    ret = 0;	
  }	
  I2C_Stop();	
  return ret;
}

void ControlPin(u8 add,u8 pin,u8 onoff)
{
	static  u8 Pin[9]={0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
	
	static	u8 PCF8574ATemp;
	static	u8 PCF8574BTemp;
	
	if(add==PCF8574A_write)
	{ 
		PCF8574ATemp=ReadPCF8574A;
		if(onoff)PCF8574ATemp|=Pin[pin]; 
		else PCF8574ATemp&=~Pin[pin];
		PCF8574_Write(add,PCF8574ATemp);
	}  
	if(add==PCF8574B_write)
	{
		PCF8574BTemp=ReadPCF8574B; 
		if(onoff)PCF8574BTemp|=Pin[pin];
		else PCF8574BTemp&=~Pin[pin];
		PCF8574_Write(add,PCF8574BTemp);
	}	
}


//PCF8574初始化函数
void Init_PCF8574(void)
{ 
    ReadPCF8574A;
}



